package com.kalaqia.image;

import android.app.Fragment;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.kalaqia.image.library.IImageLoaderStrategy;
import com.kalaqia.image.library.ImageDiskCacheStrategy;
import com.kalaqia.image.library.ImageLoaderOptions;
import com.kalaqia.image.library.ImageType;

public class GlideLoader implements IImageLoaderStrategy {

    @Override
    public void showImage(@NonNull ImageLoaderOptions options) {
        RequestManager manager = buildRequestManager(options);
        if (manager == null) return;
        RequestBuilder builder;
        if (options.getImageType() == ImageType.TYPE_BITMAP) {
            builder = manager.asBitmap().load(options.getUrl());
        } else {
            builder = manager.load(options.getUrl());
        }

        builder = zip(builder, options);
        intoTarget(options, builder);
    }

    private void intoTarget(@NonNull ImageLoaderOptions options, RequestBuilder builder) {
        Object container = options.getContainer();
        if (container != null && container instanceof ImageView) {
            builder.into((ImageView) container);
        }
    }

    public RequestManager buildRequestManager(ImageLoaderOptions options) {
        Object context = options.getContext();
        if (context == null) return null;

        if (context instanceof android.support.v4.app.Fragment) {
            return Glide.with((android.support.v4.app.Fragment) context);
        }

        if (context instanceof View) {
            return Glide.with(((View) context));
        }

        if (context instanceof AppCompatActivity) {
            return Glide.with((AppCompatActivity) options.getContext());
        }

        if (context instanceof Fragment) {
            return Glide.with((Fragment) options.getContext());
        }

        return null;
    }

    public RequestBuilder contactRequestListener(RequestBuilder builder, final ImageLoaderOptions options) {
        if (options.isListenReturn()) {
            return builder.listener(new RequestListener() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object o, Target target, boolean b) {
                    options.getImageLoadListener().onLoadFailed();
                    return false;
                }

                @Override
                public boolean onResourceReady(Object o, Object o2, Target target, DataSource dataSource, boolean b) {
                    options.getImageLoadListener().onResourceReady();
                    return false;
                }
            });
        }
        return builder;
    }

    public RequestBuilder contactRequestOptions(RequestBuilder builder, ImageLoaderOptions options) {

        RequestOptions requestOptions = new RequestOptions();

        requestOptions = requestOptions.centerCrop();

        if (options.getHolderDrawable() >= 0) {
            requestOptions.placeholder(options.getHolderDrawable());
        }

        if (options.getErrorResId() >= 0) {
            requestOptions.error(options.getErrorResId());
        }

        if (options.isSkipMemoryCache()) {
            requestOptions.skipMemoryCache(true);
        }

        if (options.getDiskCacheStrategy() != ImageDiskCacheStrategy.DEFAULT) {
            switch (options.getDiskCacheStrategy()) {
                case ImageDiskCacheStrategy.NONE:
                    requestOptions.diskCacheStrategy(DiskCacheStrategy.NONE);
                    break;
                case ImageDiskCacheStrategy.ALL:
                    requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
                    break;
                case ImageDiskCacheStrategy.SOURCE:
                    requestOptions.diskCacheStrategy(DiskCacheStrategy.DATA);
                    break;
                case ImageDiskCacheStrategy.RESULT:
                    requestOptions.diskCacheStrategy(DiskCacheStrategy.DATA);
                    break;
                default:
                    break;
            }
        }
        return builder.apply(requestOptions);
    }

    public RequestBuilder zip(RequestBuilder builder, ImageLoaderOptions options) {
        builder = contactRequestOptions(builder, options);
        builder = contactRequestListener(builder, options);
        builder = contactTransitionOptions(builder, options);
        return builder;
    }

    @Override
    public void cleanMemory(Context context) {

    }

    public RequestBuilder contactTransitionOptions(RequestBuilder builder, ImageLoaderOptions options) {
        DrawableTransitionOptions transitionOptions = new DrawableTransitionOptions();
        if (options.isCrossFade()) {
            return builder.transition(transitionOptions.crossFade());
        }
        return builder;
    }

}
